package com.yyfax.pay.depository.controller.api;

import javax.annotation.Resource;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.yyfax.framework.common.Log;
import com.yyfax.framework.common.OpResponse;
import com.yyfax.pay.common.annotation.CheckSign;
import com.yyfax.pay.common.enums.FuiouDepositStateEnum;
import com.yyfax.pay.common.exception.PayException;
import com.yyfax.pay.common.exception.PayExceptionCode;
import com.yyfax.pay.common.model.to.YYPayApiReq2;
import com.yyfax.pay.common.model.vo.ValidResult;
import com.yyfax.pay.depository.domain.FuiouArtificialRegister;
import com.yyfax.pay.depository.domain.FuiouChangeCard;
import com.yyfax.pay.depository.domain.FuiouUserRegister;
import com.yyfax.pay.depository.service.inner.FuiouChangeCardService;
import com.yyfax.pay.depository.service.inner.FuiouDepositRegisterService;
import com.yyfax.pay.depository.vo.ArtificialRegisterVO;
import com.yyfax.pay.depository.vo.FuiouChangeCardVO;
import com.yyfax.pay.depository.vo.UserRegisterVO;
import com.yyfax.pay.vo.depository.ArtificialRegisterReq;
import com.yyfax.pay.vo.depository.RspContent;
import com.yyfax.pay.vo.depository.UserChangeCardReq;
import com.yyfax.pay.vo.depository.UserChangeCardReq2;
import com.yyfax.pay.vo.depository.UserRegisterReq;

/**
 * 开户相关接口
 *
 * @author yejc
 * @date 2017-09-04
 * @since v1.0.0
 */
@RestController
public class RegisterApiController {

	private static final Logger logger = LoggerFactory.getLogger(RegisterApiController.class);

	@Resource
	private FuiouDepositRegisterService registerService;
	@Resource
	private FuiouChangeCardService changeCardService;

	/**
	 * 个人用户开户
	 * <p>
	 * 
	 * <pre>
	 * 版本2.0.7 修改记录 buyi
	 * 1.增加开户四要素幂等；
	 * 2.解耦订单保存结构；
	 * 3.增加订单保存幂等；
	 * 4.增加请求超时策略；
	 * </pre>
	 * 
	 * @param req
	 * @return
	 * @author yejc,buyi
	 * @date 2017-09-05
	 * @since v2.0.0
	 */
	@CheckSign
	@PostMapping("/api/register/normal_user")
	public OpResponse normalUserRegister(@RequestBody @Valid YYPayApiReq2<UserRegisterReq> req) throws Throwable {
		final String op = "RegisterApiController.normalUserRegister";
		UserRegisterReq userRegisterReq = req.getParams();

		OpResponse response = new OpResponse();

		// step1.校验开户，根据四要素校验，如果用户已经开户并且四要素一致，则默认开户成功。
		ValidResult validResult = registerService.validUserIdemptent(req.getMerchantCode(), userRegisterReq.getUserId(),
				userRegisterReq.getCustName(), userRegisterReq.getIdCard(), userRegisterReq.getBankCardNo(), userRegisterReq.getPhone());
		if (validResult.isOk()) {
			response.setCode(validResult.getErrCode());
			response.setDisplay(validResult.getErrMsg());
			response.setContent(new RspContent(validResult.getExt()));
			return response;
		}

		try {
			// step2.如果用户未开户，保存订单信息
			UserRegisterVO vo = registerService.saveUserRegister(req.getMerchantCode(), userRegisterReq);

			// step3.判断订单结果状态
			if (vo == null || vo.getPo() == null) {
				// 订单不存在
				response.setCode(PayExceptionCode.ORDER_NOT_FOUND.getCode());
				response.setDisplay(PayExceptionCode.ORDER_NOT_FOUND.getDesc());
				return response;
			}

			if (vo.isResult()) {
				// 订单已经出结果
				response.setCode(vo.getPo().getRespCode());
				response.setDisplay(vo.getPo().getRespDesc());
				response.setContent(new RspContent(vo.getPo().getBusiId()));
				return response;
			}

			// step4.如果订单未出结果，则调用富友开户接口
			FuiouUserRegister po = registerService.normalUserRegister(vo);

			response.setCode(po.getRespCode());
			response.setDisplay(po.getRespDesc());
			response.setContent(new RspContent(po.getBusiId()));

		} catch (PayException e) {
			logger.warn(Log.op(op).msg("【富友存管普通用户开户】出现应用级别异常").kv("YYPayApiReq2<UserRegisterReq>", req).toString(), e);
			response.setCode(e.getCode());
			response.setDisplay(e.getMessage());
		}

		return response;
	}

	/**
	 * 法人用户开户
	 * <p>
	 * 
	 * <pre>
	 * 版本2.0.7 修改记录 buyi
	 * 1.增加开户四要素幂等；
	 * 2.解耦订单保存结构；
	 * 3.增加订单保存幂等；
	 * 4.增加请求超时策略；
	 * </pre>
	 *
	 * @param req
	 * @return
	 * @author yejc,buyi
	 * @date 2017-09-05
	 * @since v2.0.0
	 */
	@CheckSign
	@PostMapping("/api/register/artificial_user")
	public OpResponse artificialUserRegister(@RequestBody @Valid YYPayApiReq2<ArtificialRegisterReq> req) throws Throwable {
		final String op = "RegisterApiController.artificialUserRegister";
		ArtificialRegisterReq artificialRegisterReq = req.getParams();
		OpResponse response = new OpResponse();

		// step1.校验开户，根据四要素校验，如果用户已经开户并且四要素一致，则默认开户成功。
		ValidResult validResult = registerService.validArtificialIdemptent(req.getMerchantCode(), artificialRegisterReq.getUserId(),
				artificialRegisterReq.getArtificialName(), artificialRegisterReq.getIdCard(), artificialRegisterReq.getPhone(),
				artificialRegisterReq.getCompanyName(), artificialRegisterReq.getBankCardNo());

		if (validResult.isOk()) {
			response.setCode(validResult.getErrCode());
			response.setDisplay(validResult.getErrMsg());
			response.setContent(new RspContent(validResult.getExt()));
			return response;
		}

		try {
			// step2.如果用户未开户，保存订单信息
			ArtificialRegisterVO vo = registerService.saveArtificialRegister(req.getMerchantCode(), artificialRegisterReq);

			// step3.判断订单结果状态
			if (vo == null || vo.getPo() == null) {
				// 订单不存在
				response.setCode(PayExceptionCode.ORDER_NOT_FOUND.getCode());
				response.setDisplay(PayExceptionCode.ORDER_NOT_FOUND.getDesc());
				return response;
			}

			if (vo.isResult()) {
				// 订单已经出结果
				response.setCode(vo.getPo().getRespCode());
				response.setDisplay(vo.getPo().getRespDesc());
				response.setContent(new RspContent(vo.getPo().getBusiId()));
				return response;
			}

			// step4.如果订单未出结果，则调用富友开户接口
			FuiouArtificialRegister po = registerService.artificialUserRegister(vo);

			response.setCode(po.getRespCode());
			response.setDisplay(po.getRespDesc());
			response.setContent(new RspContent(po.getBusiId()));

		} catch (PayException e) {
			logger.warn(Log.op(op).msg("【富友存管企业用户开户】出现应用级别异常").kv("YYPayApiReq2<UserRegisterReq>", req).toString(), e);
			response.setCode(e.getCode());
			response.setDisplay(e.getMessage());
		}

		return response;

		// ValidResult validResult = registerService.validateArtificialRegister(req.getMerchantCode(), artificialRegisterReq);
		// if (!validResult.isOk()) {
		// throw PayExceptionCode.ERROR_ILL_PARAMETER.expMsg(validResult.getErrMsg());
		// }

		// if (StringUtils.isNotBlank(validResult.getErrMsg()) && PayConstants.OPEN_ACCOUNT_SUCCESS.equals(validResult.getErrMsg())) {
		// // 幂等开户成功
		// FuiouArtificialRegister artificialRegister = registerService.searchFuiouArtificialRegister(req.getMerchantCode(), artificialRegisterReq);
		// response.setCode(artificialRegister.getRespCode());
		// response.setDisplay(artificialRegister.getRespDesc());
		// response.setContent(new RspContent(artificialRegister.getBusiId()));
		// return response;
		// }

		// FuiouArtificialRegister artificialRegister = registerService.artificialUserRegister(artificialRegisterReq, req.getMerchantCode());
		//
		// if (artificialRegister.getState().equals(FuiouDepositStateEnum.DEALING.getValue())) {
		// response.setCode(PayExceptionCode.PROCESSING.getCode());
		// response.setDisplay(PayExceptionCode.PROCESSING.getDesc());
		// } else {
		// response.setCode(artificialRegister.getRespCode());
		// response.setDisplay(artificialRegister.getRespDesc());
		// response.setContent(new RspContent(artificialRegister.getBusiId()));
		// }
		// return response;
	}

	/**
	 * 用户更换银行卡
	 *
	 * @param req
	 * @return
	 * @author yejc
	 * @date 2017-09-12
	 * @since v2.0.0
	 */
	@PostMapping("/api/register/user_change_card")
	@CheckSign
	public OpResponse userChangeCard(@RequestBody @Valid YYPayApiReq2<UserChangeCardReq> req) {
		UserChangeCardReq changeCardReq = req.getParams();
		ValidResult validResult = changeCardService.validateChangeCard(req.getMerchantCode(), changeCardReq.getBankCode(),
				changeCardReq.getImageFile1(), changeCardReq.getImageFile2());
		if (!validResult.isOk()) {
			throw PayExceptionCode.ERROR_ILL_PARAMETER.expMsg(validResult.getErrMsg());
		}

		FuiouChangeCard changeCard = changeCardService.userChangeCard(changeCardReq, req.getMerchantCode());

		OpResponse response = new OpResponse();
		RspContent rspContent = new RspContent();
		if (changeCard.getState().equals(FuiouDepositStateEnum.DEALING.getValue())) {
			response.setCode(PayExceptionCode.PROCESSING.getCode());
			response.setDisplay(PayExceptionCode.PROCESSING.getDesc());
			return response;
		} else if (changeCard.getState().equals(FuiouDepositStateEnum.ACCEPTED.getValue())) {
			rspContent.setBusiId(changeCard.getBusiId());
			rspContent.setState(RspContent.PROCESSING);
		} else if (changeCard.getState().equals(FuiouDepositStateEnum.SUCCESS.getValue())) {
			rspContent.setBusiId(changeCard.getBusiId());
			rspContent.setState(RspContent.SUCCESS);
		}
		response.setCode(changeCard.getRespCode());
		response.setDisplay(changeCard.getRespDesc());
		response.setContent(rspContent);

		return response;
	}

	@CheckSign
	@PostMapping("/api/register/user_change_card2")
	public OpResponse userChangeCard2(@RequestBody @Valid YYPayApiReq2<UserChangeCardReq2> req) throws Exception {
		UserChangeCardReq2 params = req.getParams();
		// 校验图片是否存在
		ValidResult validResult = changeCardService.validChangeCardNew(req.getMerchantCode(), params.getOrderId(), params.getBankCode(),
				params.getImageFile());
		if (!validResult.isOk()) {
			throw PayExceptionCode.ERROR_ILL_PARAMETER.expMsg(validResult.getErrMsg());
		}

		OpResponse response = new OpResponse();

		// 保存更换银行卡订单
		FuiouChangeCardVO vo = changeCardService.save(req.getMerchantCode(), params);
		if (vo.isResult()) {
			// 如果订单有结果，则直接返回
			response.setCode(vo.getPo().getRespCode());
			response.setDisplay(vo.getPo().getRespDesc());
			return response;
		}

		// 判断订单结果
		FuiouChangeCard changeCard = changeCardService.userChangeCard(vo.getPo());

		response.setCode(changeCard.getRespCode());
		response.setDisplay(changeCard.getRespDesc());
		return response;
	}

}
